package com.missilike.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.missilike.core.domain.alipay.*;
import com.missilike.core.service.IAlipayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @Author: starmile
 * @Description:
 * @Create: 2018-12-13 23:11
 **/
@Slf4j
@Service
public class AlipayService implements IAlipayService {

    private final AlipayProperties alipayProperties;
    public AlipayService(AlipayProperties alipayProperties){
        this.alipayProperties = alipayProperties;
    }

    /**
     * 发起支付
     * @param order
     * @return
     */
    @Override
    public String alipay(AlipayOrder order) {
        String orderStr = "";
        try {
            //实例化客户端
            AlipayClient alipayClient = new DefaultAlipayClient(alipayProperties.getServerUrl(), alipayProperties.getAppId(), alipayProperties.getPrivateKey(), alipayProperties.getFormat(), alipayProperties.getCharset(), alipayProperties.getAlipayPublicKey(), alipayProperties.getSignType());

            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
            AlipayTradeAppPayRequest aliRequest = new AlipayTradeAppPayRequest();

            //SDK已经封装掉了公共参数，这里只需要传入业务参数
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setPassbackParams(order.getPassbackParams());  //描述信息  添加附加数据
            model.setBody(order.getBody());                      //商品信息
            model.setSubject(order.getSubject());                //商品名称
            model.setOutTradeNo(order.getOutTradeNo());          //商户订单号(自动生成)
            model.setTimeoutExpress(order.getTimeoutExpress());  //交易超时时间
            model.setTotalAmount(order.getTotalAmount());        //支付金额
            model.setProductCode(order.getProductCode());        //销售产品码
            model.setSellerId(order.getSellerId());              //商家id
            aliRequest.setBizModel(model);
            aliRequest.setNotifyUrl(alipayProperties.getNotifyUrl());          //回调地址

            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(aliRequest);
            orderStr = response.getBody();
            //orderStr = orderStr.replace("alipay_sdk=alipay-sdk-java-3.1.0&","");
        } catch (AlipayApiException e) {
            log.error("订单生成失败: " + e.getMessage());
        }
        return orderStr;
    }

    /**
     * 验证签名
     * @param request
     * @return
     */
    @Override
    public AlipayNotifyResult signVerified(HttpServletRequest request){
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        log.info("signVerified requestParams={}", JSON.toJSON(requestParams));
        AlipayNotifyResult result = new AlipayNotifyResult();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        log.info("signVerified params={}", JSON.toJSON(params));
        //2.封装必须参数
        result.setOrderType(request.getParameter("body"));                   // 订单内容
        result.setOutTradeNo(request.getParameter("out_trade_no"));          // 商户订单号
        result.setTradeStatus(request.getParameter("trade_status"));
        result.setTradeNo(request.getParameter("trade_no"));                 //交易号

        //3.签名验证(对支付宝返回的数据验证，确定是支付宝返回的)
        boolean signVerified = false;
        try {
            //3.1调用SDK验证签名
            signVerified = AlipaySignature.rsaCheckV1(params, alipayProperties.getAlipayPublicKey(), alipayProperties.getCharset(), alipayProperties.getSignType());
        } catch (AlipayApiException e) {
            log.error("支付验证签名报错： " + e.getErrMsg());
        }
        result.setSignVerified(signVerified);
        //4.对验签进行处理
        return result;
    }

    /**
     * 支付宝提现
     * @param order
     * @return
     */
    @Override
    public AlipayCashWithdrawalResult alipayCashWithdrawal(AlipayCashWithdrawalOrder order) throws AlipayApiException {
        AlipayCashWithdrawalResult result = new AlipayCashWithdrawalResult();
        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(alipayProperties.getServerUrl(), alipayProperties.getAppId(), alipayProperties.getPrivateKey(), alipayProperties.getFormat(), alipayProperties.getCharset(), alipayProperties.getAlipayPublicKey(), alipayProperties.getSignType());
        // 设置请求参数
        Map<String, String> requestMap = new HashMap<>(16);
        requestMap.put("out_biz_no", order.getBizNo());
        requestMap.put("payee_type", "ALIPAY_LOGONID");
        requestMap.put("payee_account", order.getAccount());
        requestMap.put("amount", order.getAmount());
        requestMap.put("payee_real_name", order.getUserName());
        requestMap.put("payer_show_name", alipayProperties.getPayerShowName() + "提现");
        requestMap.put("remark", alipayProperties.getPayerShowName() + "提现");
        String json = JSON.toJSONString(requestMap);
        AlipayFundTransToaccountTransferRequest alipayRequest = new AlipayFundTransToaccountTransferRequest();
        alipayRequest.setBizContent(json);
        AlipayFundTransToaccountTransferResponse response = alipayClient.execute(alipayRequest);
        System.out.println(JSON.toJSONString(response));
        if (response.isSuccess()) {
            result.setResult(true);
            result.setMsg("提现成功");
        } else {
            result.setResult(false);
            result.setMsg(response.getSubMsg());
        }
        return result;
    }
}
